import chalk from "chalk";

import {
  accessKey,
  configVfs,
  prettyDocumentation,
  prettyQuickInfoDisplayParts,
  tightDisplayParts,
  tightDocumentation,
} from "../../../utils/typescriptVfs.js";

export function main(options: { filename?: string }) {
  const { filename } = options;
  const { getCompletions, getQuickInfo } = configVfs({
    filename,
    initialCode: `\
const inflection: GraphileBuild.Inflection = null as any;
inflection`,
  });

  let outputText = ``;
  let last = "";
  let inCode = false;
  function out(text = ""): void {
    if (text === "" && last === "" && !inCode) {
      return;
    }
    let exitCode = false;
    if (!inCode && text.startsWith("```")) {
      inCode = true;
    } else if (text.startsWith("```")) {
      exitCode = true;
    }
    outputText += (inCode ? chalk.green(text) : text) + "\n";
    last = text;
    if (exitCode) {
      inCode = false;
    }
  }
  out(
    chalk.whiteBright.bold(`# Custom \`GraphileBuild.Inflection\` Reference`),
  );
  out();
  out(`\
This reference was autogenerated by \`graphile inflection list\` using your
local configuration file to determine the inflectors that are available based
on the plugins and presets you use. You should regenerate it from time to time
(for example, when you upgrade a module, or add/remove modules).`);
  out();

  const completions = [...(getCompletions(".")?.entries ?? [])];
  completions.sort((a, z) => a.name.localeCompare(z.name, "en-US"));

  let later: Array<string | undefined> = [];
  function outLater(str?: string): void {
    later.push(str);
  }
  const entries: string[] = [];
  const INDENT = 2;
  for (const entry of completions) {
    const key = entry.name;
    const withProperty = accessKey(key);
    const info = getQuickInfo(withProperty);
    //entries.push(
    //  `${chalk.cyanBright(key)}${prettyQuickInfoDisplayParts(info)};`,
    //);
    const doc = tightDocumentation(info, 80 - INDENT - 7);
    entries.push(
      `${
        doc
          ? chalk.gray(`/** ${doc} */
`)
          : ``
      }${chalk.cyanBright(key)}${tightDisplayParts(
        info,
        80 - INDENT - key.length,
      )}`,
    );

    outLater(chalk.whiteBright.bold(`## ${chalk.cyanBright.bold(key)}`));
    outLater();
    outLater(prettyDocumentation(info?.documentation));
    outLater();
    outLater("```ts");
    outLater(key + prettyQuickInfoDisplayParts(info));
    outLater("```");
    outLater();
  }

  if (entries.length) {
    out("```ts");
    out(chalk.cyanBright(`interface GraphileBuild.Inflection`) + ` {`);
    for (const entry of entries) {
      out("  " + entry.replace(/\n/g, "\n  "));
    }
    out("}");
    out("```");
    out();
  }
  for (const line of later) {
    out(line);
  }
  later = [];
  return outputText.trim() + "\n";
}
